﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using RabbitMQ.Client;

namespace TestRabbitMQ
{
    public class PublishClient : IPublishClient
    {
        private ConnectionFactory _factory;
        private IConnection _connection;
        private IModel _channel;

        private string exchangeName = "FanoutChange";
        public PublishClient(IOptions<RabbitMQConfig> options)
        {
            if (_connection == null)
            {
                var option = options.Value;
                //创建连接工厂
                _factory = new ConnectionFactory
                {
                    UserName = option.UserName,//用户名
                    Password = option.Password,//密码
                    HostName = option.HostName,//rabbitmq ip
                    AutomaticRecoveryEnabled = true,//启动网络断线重连
                    NetworkRecoveryInterval = TimeSpan.FromSeconds(10),//重连间隔时间
                    TopologyRecoveryEnabled = true//重新声明交换机/队列等信息
                };
                //创建连接
                _connection = _factory.CreateConnection();
                //创建通道
                _channel = _connection.CreateModel();

                ////定义一个 Topic 类型交换机
                //_channel.ExchangeDeclare(exchangeName, ExchangeType.Topic, false, false, null);
            }
        }

        public bool PublishFanout<T>(string queue, string routeKey, T msgobj)
        {
            var msg = JsonConvert.SerializeObject(msgobj);

            _channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, false, false, null);   
            //定义队列
            _channel.QueueDeclare(queue, false, false, false, null);
            //将队列绑定到交换机
            _channel.QueueBind(queue, exchangeName, routeKey, null);
            // 设置消息属性 
            var properties = _channel.CreateBasicProperties();
            properties.DeliveryMode = 2; //消息是持久的，存在并不会受服务器重启影响

            Console.WriteLine("\nRabbitMQ连接成功");

            var sendBytes = Encoding.UTF8.GetBytes(msg);
            //设置Confirm模式，保证消息传递  生产者==>服务端  正常
            _channel.ConfirmSelect();

            do
            {
                //发布消息
                _channel.BasicPublish(exchangeName, queue, properties, sendBytes);

            } while (!_channel.WaitForConfirms()); //确认消息从 生产者==>服务端 正常，发送失败则重发

            return true;
        }

        public bool PublishTopic<T>(string queue, T msgobj)
        {
            var msg = JsonConvert.SerializeObject(msgobj);

            //声明一个队列
            _channel.QueueDeclare(queue, false, false, false, null);

            ////绑定交换机
            //_channel.QueueBind(queue, exchangeName, "", null);

            // 设置消息属性 
            var properties = _channel.CreateBasicProperties();
            properties.DeliveryMode = 2; //消息是持久的，存在并不会受服务器重启影响

            Console.WriteLine("\nRabbitMQ连接成功");

            var sendBytes = Encoding.UTF8.GetBytes(msg);
            //设置Confirm模式，保证消息传递  生产者==>服务端  正常
            _channel.ConfirmSelect();

            do
            {
                //发布消息
                _channel.BasicPublish("", queue, properties, sendBytes);

            } while (!_channel.WaitForConfirms()); //确认消息从 生产者==>服务端 正常，发送失败则重发

            //_channel.Close();
            //_connection.Close();
            return true;
        }
    }
}
